﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestByWire.Tutorial.Domain;

namespace TestByWire.Tutorial
{
    [TestClass]
    [UseStub(typeof(IDataLayer), typeof(DataLayer))]
    [UseStubLateBound(typeof(IDataLayer), "_dataLayerEx", typeof(DataLayer))]
    public class ResettingStubs : TestTarget<LogicLayerEx>
    {
        [TestMethod]
        [ResetStub(typeof(IDataLayer))]
        public void MustBeAbleToInjectProxyStubIntoConstructor()
        {
            When.Calling.Execute();

            Then<IDataLayer>.Should(d => d.Execute());
        }

        [TestMethod]
		[ResetStub(typeof(IDataLayer), "_dataLayerEx")]
        public void MustBeAbleToResetLateBoundStub()
        {
            try
            {
                When.Calling.ExecuteEx();
            }
            catch (NullReferenceException)
            {
                return;
            }

            Assert.Fail("ExecuteEx should have thrown exception");
        }

        [TestMethod]
		[ResetStub(typeof(IDataLayer), "_dataLayerEx")]
        public void InjectedStubMustBeLeftAlone()
        {
            string result = When.Calling.Execute();

            Assert.AreEqual(DataLayer.UniqueString, result);
        }

        [TestMethod]
        [ResetStub(typeof(IDataLayer))]
        public void LateBoundStubMustBeLeftAlone()
        {
            string result = When.Calling.ExecuteEx();

            Assert.AreEqual(DataLayer.UniqueString, result);
        }

        [TestMethod]
		[UseStubLateBound(typeof(IDataLayer), "_dataLayerEx")]
        public void MustBeAbleToChangeLateBoundStubToAProxy()
        {
            Given.That<IDataLayer>("_dataLayerEx", d => d.Execute()).Returns("Testing");

            var result = When.Calling.ExecuteEx();

            Assert.AreEqual("Testing", result);
        }
    }
}
